package com.zzl.springboot_mybatis_demo.handler;

import com.gitee.yongzhuzl.commonutil.util.ExceptionUtil;
import com.gitee.yongzhuzl.commonutil.util.result.ResponseResult;
import com.zzl.springboot_mybatis_demo.exception.ResponseException;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.exceptions.TooManyResultsException;
import org.mybatis.spring.MyBatisSystemException;
import org.springframework.transaction.CannotCreateTransactionException;
import org.springframework.web.HttpMediaTypeNotSupportedException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.sql.SQLException;

/**
 * description: 全局异常处理handler
 * @author 朱正磊
 * @date 2019-08-29 10:42:11
 */
@Slf4j
@ControllerAdvice
public class MyExceptionHandler {

    /**
     * description：拦截自定义异常（主要是处理service层抛出的异常），响应json格式数据
     * user 朱正磊
     * time 2019-04-09 11:29
     * @param e 异常对象
     * @return 返回响应对象
     */
    @ExceptionHandler(ResponseException.class)
    @ResponseBody
    public ResponseResult handleResponseException(ResponseException e) {
        log.info("自定义异常信息：{}", e);
        return ResponseResult.buildResult(e.getCode(), e.getMessage());
    }

    /**
     * description: 拦截未知的异常，响应json格式数据
     * @author 朱正磊
     * @date 2019-10-17 19:01:40
     * @param e 异常对象
     * @return 返回响应对象
     */
    @ExceptionHandler(RuntimeException.class)
    @ResponseBody
    public ResponseResult handleRuntimeException(RuntimeException e) {
        log.error("发生未知运行时异常：类===》{}，原因===》{}，大概信息===》{}，具体信息===》{}",
                e.getClass(), e.getCause(), e.getMessage(), ExceptionUtil.logExceptionStack(e));
        if (e instanceof NullPointerException) {
            return ResponseResult.buildResult(4001, "空指针引用异常！");
        } else if (e instanceof ClassCastException) {
            return ResponseResult.buildResult(4002, "类型强制转换异常！");
        } else if (e instanceof NumberFormatException) {
            return ResponseResult.buildResult(4003, "数字格式异常！");
        } else if (e instanceof IllegalArgumentException) {
            return ResponseResult.buildResult(4005, "传递非法参数异常！");
        } else if (e instanceof ArithmeticException) {
            return ResponseResult.buildResult(4006, "算术运算异常！");
        } else if (e instanceof ArrayStoreException) {
            return ResponseResult.buildResult(4007, "向数组中存放与声明类型不兼容对象异常！");
        } else if (e instanceof IndexOutOfBoundsException) {
            return ResponseResult.buildResult(4008, "下标越界异常！");
        } else if (e instanceof NegativeArraySizeException) {
            return ResponseResult.buildResult(4009, "创建一个大小为负数的数组错误异常！");
        } else if (e instanceof SecurityException) {
            return ResponseResult.buildResult(4010, "安全异常！");
        } else if (e instanceof UnsupportedOperationException) {
            return ResponseResult.buildResult(4011, "不支持的操作异常！");
        } else if (e instanceof CannotCreateTransactionException) {
            return ResponseResult.buildResult(4012, "数据库服务获取连接中断！");
        } else if (e instanceof MyBatisSystemException) {
            Throwable cause = e.getCause();
            if (cause instanceof TooManyResultsException) {
                log.info("异常根源信息：{}", cause.getMessage());
                return ResponseResult.buildResult(4013, "查询结果最多应该只有一条，但是却查出多条！");
            }
        }
        return ResponseResult.buildResult(4000, "服务器已挂！请速速联系后台开发人员！");
    }

    /**
     * description: 拦截未知的异常，响应json格式数据
     * @author 朱正磊
     * @date 2019-10-17 19:01:40
     * @param e 异常对象
     * @return 返回响应对象
     */
    @ExceptionHandler(Exception.class)
    @ResponseBody
    public ResponseResult defaultErrorHandler(Exception e) {
        log.error("发生未知非运行时异常：类===》{}，原因===》{}，大概信息===》{}，具体信息===》{}",
                e.getClass(), e.getCause(), e.getMessage(), ExceptionUtil.logExceptionStack(e));
        if (e instanceof NoSuchMethodException) {
            return ResponseResult.buildResult(5001, "方法未找到异常！");
        } else if (e instanceof FileNotFoundException) {
            return ResponseResult.buildResult(5002, "文件未找到异常！");
        } else if (e instanceof SQLException) {
            return ResponseResult.buildResult(5003, "操作数据库异常！");
        } else if (e instanceof ClassNotFoundException) {
            return ResponseResult.buildResult(5004, "类文件未找到异常！");
        } else if (e instanceof IOException) {
            return ResponseResult.buildResult(5005, "输入输出异常！");
        } else if (e instanceof HttpMediaTypeNotSupportedException) {
            return ResponseResult.buildResult(5006, "客户端请求参数格式错误！");
        }
        return ResponseResult.buildResult(5000, "服务器发生未知异常！请尽快联系后台开发人员！");
    }

}
